package com.baoyouqun.controller.weixin;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Validator;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baoyouqun.API.friend.FriendRelationService;
import com.baoyouqun.API.friend.domain.FriendRelation;
import com.baoyouqun.base.utils.ConvertUtils;
import com.baoyouqun.domain.Enum.DemandCollectionStatusEnum;
import com.baoyouqun.domain.Enum.DemandTypeEnum;
import com.baoyouqun.domain.Enum.IndustryEnum;
import com.baoyouqun.domain.Enum.ResourceTypeEnum;
import com.baoyouqun.domain.UpdateCmd.UserInfoSettingDTO;
import com.baoyouqun.domain.UpdateCmd.UserUpdateCmd;
import com.baoyouqun.domain.VO.*;
import com.baoyouqun.entity.Demand;
import com.baoyouqun.entity.DemandCollection;
import com.baoyouqun.entity.ResourceType;
import com.baoyouqun.entity.UserAddress;
import com.baoyouqun.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.apache.poi.util.StringUtil;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/wx/user")
@Api(tags = "小程序_我的界面接口")
public class WxUserController {

    @Resource
    private UserService userService;
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private RoleService roleService;
    @Resource
    private ResourceTypeService resourceTypeService;
    @Resource
    private VirtualNumberService virtualNumberService;
    @Resource
    private DemandService demandService;
    @Resource
    private DemandCollectionService demandCollectionService;
    @Resource
    private UserVipTimeService userVipTimeService;
    @Resource
    private UserPointsService userPointsService;
    @Resource
    private UserAddressService userAddressService;
    @Resource
    private SystemConfigService systemConfigService;
    @Resource
    private FriendRelationService friendRelationService;


    @GetMapping("resourceTypeList")
    @ApiOperation("资源类型选择列表（按拥有/需要分组）")
    public SingleResponse<ResourceTypeGroupVO> selectResourceTypeList() {
        // 1. 获取所有资源类型
        List<ResourceType> allResourceTypes = resourceTypeService.list();
        List<ResourceTypeVO> list = ConvertUtils.copyBeanList(allResourceTypes, ResourceTypeVO.class);

        Map<String, List<ResourceTypeVO>> groupedMap = list.stream()
                .collect(Collectors.groupingBy(ResourceTypeVO::getTypeCategory));

        List<ResourceTypeVO> ownResourceList = new ArrayList<>(groupedMap.getOrDefault(ResourceTypeEnum.OWN.getValue(), Collections.emptyList()));

        List<ResourceTypeVO> needResourceList = new ArrayList<>(groupedMap.getOrDefault(ResourceTypeEnum.NEED.getValue(), Collections.emptyList()));

        ResourceTypeGroupVO resultVO = new ResourceTypeGroupVO();
        resultVO.setOwnResourceList(ownResourceList);  // 前端可通过"ownResourceList"获取拥有的资源
        resultVO.setNeedResourceList(needResourceList); // 前端可通过"needResourceList"获取需要的资源

        return SingleResponse.of(resultVO);
    }

    @PostMapping("/setUserInfo")
    @ApiOperation("完善个人基本信息")
    public Response setUserInfo(@Valid @RequestBody UserInfoSettingDTO dto) {
        UserUpdateCmd userInfo = dto.getUserUpdateCmd();
        userInfo.setId(StpUtil.getLoginIdAsString());
        return userService.setUserInfo(userInfo, dto.getResourceList());
    }


    @GetMapping("industryEnumList")
    @ApiOperation("所在行业选择列表")
    public Response industryEnumList() {
        Map<String, List<String>> industryEnum = IndustryEnum.getAllIndustryMap();
        return SingleResponse.of(industryEnum);
    }

    //    @SaIgnore
    @GetMapping("wxMyPage")
    @ApiOperation("我的界面数据接口")
    public SingleResponse<WxMyPageVO> wxMyPage() {
        WxMyPageVO wxMyPageVO = new WxMyPageVO();
        if (!StpUtil.isLogin()) {
            return SingleResponse.of(wxMyPageVO);
        }

        // 获取当前会话用户信息
        UserVO userVO = userService.selectById(StpUtil.getLoginIdAsString());
        String userId = userVO.getId();

        wxMyPageVO.setUserId(userId);
        wxMyPageVO.setImUserSig(userVO.getImUserSig());
        wxMyPageVO.setName(userVO.getName());
        wxMyPageVO.setHeadImg(userVO.getHeadImg());
        wxMyPageVO.setSex(userVO.getSex()); // 修复原代码的性别赋值错误
        wxMyPageVO.setCellphone(userVO.getCellphone());
        wxMyPageVO.setExtraPhones(userVO.getExtraPhones());
        wxMyPageVO.setJob(userVO.getJob());
        wxMyPageVO.setCompany(userVO.getCompany());
        wxMyPageVO.setProvince(userVO.getProvince());
        wxMyPageVO.setCity(userVO.getCity());
        wxMyPageVO.setDistrict(userVO.getDistrict());
        wxMyPageVO.setBaoZhiHao(userVO.getBaoZhiHao());

        // 1. 获取我的需求数量（需要的资源）
        Long neededResourcesNum = demandService.count(
                new LambdaQueryWrapper<Demand>()
                        .eq(Demand::getUserId, userId)
                        .eq(Demand::getType, DemandTypeEnum.NEED)
        );
        

        // 2. 获取我的资源数量（拥有的资源）
        Long ownedResourcesNum = demandService.count(
                new LambdaQueryWrapper<Demand>()
                        .eq(Demand::getUserId, userId)
                        .eq(Demand::getType, DemandTypeEnum.OWN)
        );

        Long myFriendNum = friendRelationService.count(
                new LambdaQueryWrapper<FriendRelation>()
                        .eq(FriendRelation::getUserId, userId)
                        .eq(FriendRelation::getStatus, 1) // 有效收藏
        );

        // 3. 获取我的收藏数量（假设有收藏服务和实体类）
        Long myCollectionsNum = demandCollectionService.count(
                new LambdaQueryWrapper<DemandCollection>()
                        .eq(DemandCollection::getUserId, userId)
                        .eq(DemandCollection::getStatus, DemandCollectionStatusEnum.VALID) // 有效收藏
        );

        // 4. 获取用户积分数量
        UserPointsVO userPoints = userPointsService.getByUserId(userId);
        Integer pointsNum = userPoints != null ? userPoints.getCurrentPoints() : 0;

        // 5. 获取会员等级和剩余天数
        String memberLevel = "";
        String memberExpires = "0天";

        // 查询用户当前有效的会员记录
        UserVipTimeVO currentVip = userVipTimeService.getCurrentVip(userId);
        if (currentVip != null) {
            // 获取会员等级名称
            memberLevel = currentVip.getVipLevelName();

            // 计算剩余天数
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime endTime = currentVip.getEndTime();
            if (endTime.isAfter(now)) {
                long days = ChronoUnit.DAYS.between(now, endTime);
                memberExpires = days + "天";
            } else {
                memberExpires = "已过期";
            }
        }


        wxMyPageVO.setNeededResourcesNum(neededResourcesNum);
        wxMyPageVO.setOwnedResourcesNum(ownedResourcesNum);
        wxMyPageVO.setMyCollectionsNum(myCollectionsNum);
        wxMyPageVO.setMyFriendNum(myFriendNum);
        wxMyPageVO.setPointsNum(pointsNum);
        wxMyPageVO.setMemberLevel(memberLevel);
        wxMyPageVO.setMemberExpires(memberExpires);


        // 计算资料完成度
        List<String> properties = Arrays.asList(
                userVO.getName(),
                userVO.getSex() != null ? userVO.getSex() : null,
                userVO.getCellphone(),
                userVO.getJob(),
                userVO.getCompany(),
                userVO.getProvince(),
                userVO.getCity(),
                userVO.getDistrict()
        );

        // 统计已填写的属性数量
        long filledCount = properties.stream()
                .filter(prop -> prop != null && !prop.trim().isEmpty())
                .count();
        int dataCompletion = (int) Math.round(((double) filledCount / properties.size()) * 100);
        wxMyPageVO.setDataCompletion(dataCompletion);


        wxMyPageVO.setReceivedInfo("未填写");
        UserAddress userAddress = userAddressService.getByUserId(userId);
        if (Objects.nonNull(userAddress)) {
            wxMyPageVO.setReceivedInfo("已填写");
        }

        InviteFriendDTO inviteFriend = systemConfigService.getInviteFriend();
        if (Objects.nonNull(inviteFriend)) {
            wxMyPageVO.setInviteFriendsTips(inviteFriend.getRewardAmount().toString());
        }
        return SingleResponse.of(wxMyPageVO);
    }


    @PutMapping("update")
    @ApiOperation("修改基本信息")
    public Response update(@Valid @RequestBody UserUpdateCmd cmd) {
        return userService.update(cmd);
    }

    @GetMapping("/getContactMobileByUserId")
    @ApiOperation("获取用户联系方式")
    public SingleResponse<String> getContactMobileByUserId(String userId) {
        if (StringUtil.isBlank(userId)) {
            return SingleResponse.of("");
        }
        UserVO user = userService.selectById(userId);
        if (Objects.nonNull(user)) {
            return SingleResponse.of("");
        }
        if (CollUtil.isEmpty(user.getExtraPhones())) {
            return SingleResponse.of(user.getCellphone());
        } else {
            return SingleResponse.of(user.getExtraPhones().get(0));
        }
    }

    @GetMapping("/getUserExtraPhonesInfo")
    @ApiOperation("修改联系电话页面数据")
    public SingleResponse<VirtualNumberVO> getUserExtraPhonesInfo() {
        String userId = StpUtil.getLoginIdAsString();
        return virtualNumberService.getUserExtraPhonesInfo(userId);
    }


    @PostMapping("/setUserExtraPhones")
    @ApiOperation("修改联系电话")
    public Response setUserExtraPhones(@Valid @RequestBody List<String> extraPhones) {
        if (CollUtil.isEmpty(extraPhones)) {
            return Response.buildFailure("100301", "联系号码不能为空");
        }
        for (String phone : extraPhones) {
            if (!Validator.isMobile(phone)) {
                return Response.buildFailure("100102", "手机号码格式不正确[" + phone + "]");
            }
        }
        String userId = StpUtil.getLoginIdAsString();
        return userService.setUserExtraPhones(userId, extraPhones);
    }


    @GetMapping("userHome")
    @ApiOperation("个人空间")
    public SingleResponse<UserHomeVO> userHome(String userId) {
        return SingleResponse.of(userService.userHome(userId)
        );
    }

    /**
     * 分页查询公开豹友列表（支持筛选：在线、VIP、老乡/地区）
     *
     * @param current    当前页（默认1）
     * @param size       每页条数（默认10）
     * @param isOnline   是否筛选在线用户（true=仅在线，false=全部，默认false）
     * @param isVip      是否筛选VIP用户（true=仅VIP，false=全部，默认false）
     * @param sameRegion 是否筛选老乡（true=同省/同市，false=全部，默认false）
     * @return 分页公开豹友列表
     */
    @GetMapping("/publicFriends/page")
    @ApiOperation("分页查询公开豹友列表")
    public SingleResponse<IPage<PublicFriendVO>> pagePublicFriends(
            @ApiParam(value = "当前页", defaultValue = "1") @RequestParam(required = false, defaultValue = "1") Long current,
            @ApiParam(value = "每页条数", defaultValue = "10") @RequestParam(required = false, defaultValue = "10") Long size,
            @ApiParam(value = "是否仅在线用户") @RequestParam(required = false, defaultValue = "false") Boolean isOnline,
            @ApiParam(value = "是否仅VIP用户") @RequestParam(required = false, defaultValue = "false") Boolean isVip,
            @ApiParam(value = "是否仅老乡（同省/同市）") @RequestParam(required = false, defaultValue = "false") Boolean sameRegion,
            @ApiParam(value = "城市") @RequestParam(required = false, defaultValue = "") String cityCode
    ) {

        // 获取当前登录用户ID（排除自己）
        String loginUserId = StpUtil.getLoginIdAsString();
        IPage<PublicFriendVO> friendPage = userService.pagePublicFriends(
                loginUserId, current, size, isOnline, isVip, sameRegion, cityCode
        );
        return SingleResponse.of(friendPage);
    }

    /**
     * 搜索公开豹友（按昵称/手机号模糊匹配）
     *
     * @param keyword 搜索关键词（昵称或手机号）
     * @param current 当前页（默认1）
     * @param size    每页条数（默认10）
     * @return 搜索结果分页列表
     */
    @GetMapping("/publicFriends/search")
    @ApiOperation("搜索公开豹友（昵称/手机号）")
    public SingleResponse<IPage<PublicFriendVO>> searchPublicFriends(
            @ApiParam(value = "搜索关键词（昵称/手机号）", required = true) @RequestParam String keyword,
            @ApiParam(value = "当前页", defaultValue = "1") @RequestParam(required = false, defaultValue = "1") Long current,
            @ApiParam(value = "每页条数", defaultValue = "10") @RequestParam(required = false, defaultValue = "10") Long size) {

        String loginUserId = StpUtil.getLoginIdAsString();
        IPage<PublicFriendVO> searchPage = userService.searchPublicFriends(
                loginUserId, keyword, current, size
        );
        return SingleResponse.of(searchPage);
    }

    @PostMapping("/cancelAccount")
    @ApiOperation("用户自行注销账户")
    public Response cancelAccount() {
        // 验证用户是否登录
        if (!StpUtil.isLogin()) {
            return Response.buildFailure("100101", "用户未登录");
        }

        // 获取当前登录用户ID
        String userId = StpUtil.getLoginIdAsString();
        // 调用服务层执行注销逻辑
        Response response = userService.cancelAccount(userId);

        // 注销成功后退出登录
        if (response.isSuccess()) {
            StpUtil.logout();
        }

        return response;
    }
}